{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "0e1b9f4a",
   "metadata": {},
   "source": [
    "## 元类\n",
    "- 什么是元类？\n",
    "    - 动态创建类\n",
    "    - 元类 -> 类\n",
    "    - 类 -> 对象\n",
    "\n",
    "- 用途？\n",
    "    - 可以动态创建类\n",
    "\n",
    "- 如何使用？type()\n",
    "    1. 查看目标对象的数据类型\n",
    "    2. 可以使用type，动态创建类\n",
    "\n",
    "语法: 类 = type(类名, (父类...), {属性，方法})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "60c39e20",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-13T13:37:23.492372Z",
     "start_time": "2023-10-13T13:37:23.481653Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<__main__.Person object at 0x107537bb0>\n",
      "3\n",
      "狗狗趴着睡觉\n",
      "Yellow\n",
      "动物需要吃东西\n",
      "Dog\n"
     ]
    }
   ],
   "source": [
    "# 创建一个默认父类，不包含任何属性方法的类\n",
    "Person = type('Person', (), {})\n",
    "\n",
    "# 可以用Person创建对象\n",
    "p1 = Person()\n",
    "print(p1)\n",
    "\n",
    "\n",
    "class Animal():\n",
    "    def __init__(self, color):\n",
    "        self.color = color\n",
    "\n",
    "    def eat(self):\n",
    "        print(\"动物需要吃东西\")\n",
    "\n",
    "\n",
    "def sleep(self):\n",
    "    print(\"狗狗趴着睡觉\")\n",
    "\n",
    "\n",
    "# 使用 type动态创建一个类，父类就是Animal\n",
    "Dog = type('Dog', (Animal,), {'age': 3, 'sleep': sleep})\n",
    "dog = Dog('Yellow')\n",
    "print(dog.age)\n",
    "dog.sleep()\n",
    "\n",
    "# 继承了父类中的特性\n",
    "print(dog.color)\n",
    "\n",
    "# 继承了父类的方法\n",
    "dog.eat()\n",
    "\n",
    "print(Dog.__name__)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f1b9fa23",
   "metadata": {},
   "source": [
    "## 类装饰器"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ef2feec8",
   "metadata": {},
   "source": [
    "在不修改函数源代码的前提下，增加新的功能"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "073f02c2",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-13T13:40:58.644893Z",
     "start_time": "2023-10-13T13:40:58.639390Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "--初始化--\n",
      "func name is test\n",
      "--装饰器中的功能--\n",
      "--test 函数---\n"
     ]
    }
   ],
   "source": [
    "class Test(object):\n",
    "    def __init__(self, func):\n",
    "        print(\"--初始化--\")\n",
    "        print(\"func name is %s\" % func.__name__)\n",
    "        self.__func = func\n",
    "        \n",
    "    # 重写该方法后，对象可以直接进行调用\n",
    "    def __call__(self):\n",
    "        print(\"--装饰器中的功能--\")\n",
    "        self.__func()\n",
    "\n",
    "        \n",
    "\n",
    "@Test # @Test 等价于 test = Test(test) 装饰器特性\n",
    "def test():\n",
    "    print('--test 函数---')\n",
    "\n",
    "\n",
    "# 本身test指向函数test，但是装饰器将test指向了对象。\n",
    "#  对象本身不可以被调用，但是重写__call__方法之后则会被调用\n",
    "test()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6477951f",
   "metadata": {},
   "source": [
    "## 对象池\n",
    "\n",
    "对象池：\n",
    "1. 数值类型\n",
    "    - 小整数池\n",
    "         - 小整数：  [-5, 256]\n",
    "         - 程序开始时，一次性加载到内存\n",
    "         - LEGB(局部变量，闭包中的变量，全局变量，内建变量)\n",
    "         - 全局都是同一个\n",
    "\n",
    "    - 大整数池\n",
    "         - 每创建一个不是小整数范围内的变量，都会被自动存储到大整数池中\n",
    "\n",
    "2. 字符串\n",
    "    - intern机制\n",
    "         - 每个单词(字符串)，不夹杂空格或者其他符号，默认开启intern机制，共享内存，靠引用计数决定是否销毁"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "8ab4b9f2",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-13T13:47:23.366013Z",
     "start_time": "2023-10-13T13:47:23.358918Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "4367209936\n",
      "4367209936\n"
     ]
    }
   ],
   "source": [
    "# 发现删除a后，b的地址依旧是删除之前的那个地址(是否删除，小整数都常驻内存)\n",
    "a = 100\n",
    "print(id(a))\n",
    "\n",
    "del a\n",
    "b = 100\n",
    "print(id(b))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fb237a6e",
   "metadata": {},
   "source": [
    "## 垃圾回收机制：GC机制\n",
    "Python：\n",
    "1. 引用计数机制为主\n",
    "    - 如何获取一个对象的引用计数？\n",
    "        - sys.getrefcount(a)\n",
    "        - 刚创建对象引用计数为2\n",
    "\n",
    "    - 增加引用计数操作\n",
    "        1. 如果有新的对象对象使用该对象，+1\n",
    "        2. 装进列表+1\n",
    "        3. 作为函数参数+1\n",
    "        \n",
    "    - 减少引用计数操作\n",
    "        1. 如果有新的对象对象使用该对象，新对象不再使用-1\n",
    "        2. 从列表中移除-1\n",
    "        3. 函数调用结束\n",
    "        4. del 显示销毁\n",
    "\n",
    "\n",
    "2. 隔代回收为辅助\n",
    "    - 原理：随着时间的推进，程序冗余对象逐渐增多，达到一定数量（阈值），系统进行回收\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "44b61533",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-13T14:32:02.775704Z",
     "start_time": "2023-10-13T14:32:02.764763Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "开辟内存空间\n",
      "创建对象at:0x10793b1f0\n",
      "a的引用计数为:2\n",
      "a的引用计数为:3\n",
      "a的引用计数为:4\n",
      "<__main__.AA object at 0x10793b1f0>\n",
      "a的引用计数为:6\n",
      "a的引用计数为:4\n",
      "----------------------\n",
      "a的引用计数为:3\n",
      "a的引用计数为:2\n"
     ]
    }
   ],
   "source": [
    "\"\"\"垃圾回收机制\"\"\"\n",
    "import sys\n",
    "\n",
    "class AA():\n",
    "    def __new__(cls, *args, **kwargs):\n",
    "        \"\"\"创建对象开辟内存时调用\"\"\"\n",
    "        \n",
    "        print(\"开辟内存空间\")\n",
    "        return super(AA, cls).__new__(cls)\n",
    "    \n",
    "\n",
    "    def __init__(self):\n",
    "        \"\"\"初始化方法\"\"\"\n",
    "        print(\"创建对象at:%s\" % hex(id(self)))\n",
    "\n",
    "\n",
    "    def __del__(self):\n",
    "        \"\"\"对象被系统回之前，会调用该方法\"\"\"\n",
    "        print(\"%s say bye bye\" % hex(id(self)))\n",
    "\n",
    "\n",
    "def test1(aaa):\n",
    "    print(aaa)\n",
    "    print('a的引用计数为:%d' % sys.getrefcount(a))\n",
    "\n",
    "\n",
    "a = AA()\n",
    "print('a的引用计数为:%d' % sys.getrefcount(a))\n",
    "\n",
    "b = a\n",
    "print('a的引用计数为:%d' % sys.getrefcount(a))\n",
    "\n",
    "list1 = [a]\n",
    "print('a的引用计数为:%d' % sys.getrefcount(a))\n",
    "\n",
    "test1(a) # 作为函数参数时计数+1，创建形参时再+1 \n",
    "\n",
    "# 函数调用结束，计数-1，形参销毁再-1\n",
    "print('a的引用计数为:%d' % sys.getrefcount(a))\n",
    "print('----------------------')\n",
    "\n",
    "b = 100\n",
    "print('a的引用计数为:%d' % sys.getrefcount(a))\n",
    "\n",
    "list1.remove(a)\n",
    "print('a的引用计数为:%d' % sys.getrefcount(a))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bd8552e2",
   "metadata": {},
   "source": [
    "**gc模块的使用：**\n",
    "\n",
    "```\n",
    "# 获取当前自动执行垃圾回收的计数器，返回一个长度为3的列表\n",
    "1、gc.get_count()\n",
    "\n",
    "# 获取gc模块中自动执行垃圾回收的频率\n",
    "2、gc.get_threshold()\n",
    "\n",
    "# 设置自动执行垃圾回收的频率\n",
    "3、gc.set_threshold(threshold0[,threshold1,threshold2])\n",
    "\n",
    "# python3默认开启gc机制，可以使用该方法手动关闭gc机制\n",
    "4、gc.disable()\n",
    "\n",
    "# 手动调用垃圾回收机制回收垃圾\n",
    "5、gc.collect()\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "12f1ce57",
   "metadata": {
    "ExecuteTime": {
     "start_time": "2023-10-13T14:42:20.154Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "new\n",
      "object:born at 0x1044a8520\n",
      "new\n",
      "object:born at 0x1044a8e20\n",
      "(200, 10, 10)\n",
      "(47, 10, 0)\n",
      "new\n",
      "object:born at 0x1040bdac0\n",
      "new\n",
      "object:born at 0x1044a8ee0\n",
      "(200, 10, 10)\n",
      "(43, 10, 0)\n",
      "new\n",
      "object:born at 0x1044a8880\n",
      "new\n",
      "object:born at 0x1044a8fd0\n",
      "(200, 10, 10)\n",
      "(45, 10, 0)\n"
     ]
    }
   ],
   "source": [
    "\"\"\"隔代回收机制\"\"\"\n",
    "\n",
    "import gc\n",
    "import time\n",
    "\n",
    "\n",
    "class AA():\n",
    "    def __new__(cls, *args, **kwargs):\n",
    "        print(\"new\")\n",
    "        return super(AA, cls).__new__(cls)\n",
    "\n",
    "    def __init__(self):\n",
    "        print(\"object:born at %s\" % hex(id(self)))\n",
    "\n",
    "    def __del__(self):\n",
    "        print(\"%s 被系统回收\" % hex(id(self)))\n",
    "\n",
    "\n",
    "def start():\n",
    "    while True:\n",
    "        # 创建对象\n",
    "        a = AA()\n",
    "        b = AA()\n",
    "        \n",
    "        # 相互引用 -- 导致对象无法通过 del删除\n",
    "        a.v = b\n",
    "        b.v = a\n",
    "        del a\n",
    "        del b\n",
    "        \n",
    "        # 获取gc模块中自动执行垃圾回收的频率\n",
    "        print(gc.get_threshold())\n",
    "        \n",
    "        # 获取当前自动执行垃圾回收的计数器\n",
    "        print(gc.get_count())\n",
    "        \n",
    "        time.sleep(3)\n",
    "\n",
    "# 设置自动执行垃圾回收的频率\n",
    "# 三个链表, 零代链表上的对象(新创建的对象都加入到零代链表), 引用数都是一,\n",
    "# 每增加一个指针, 引用加一, 随后python会检测列表中的互相引用的对象, 根据规则减掉其引用计数. \n",
    "# GC算法对链表一的引用减一,引用为0的,清除,不为0的到链表二, 链表二也执行GC算法, 链表三一样. \n",
    "gc.set_threshold(200, 10, 10)\n",
    "start()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6f6bdb71",
   "metadata": {},
   "source": [
    "## 内建函数"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e7c5b670",
   "metadata": {},
   "source": [
    "### range函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "c2639318",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-13T14:46:07.440244Z",
     "start_time": "2023-10-13T14:46:07.431154Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 2 3 4 5 6 7 8 9 10 \n",
      "1 3 5 7 9 \n",
      "10 9 8 7 6 5 4 3 2 1 0 \n",
      "10 8 6 4 2 0 \n",
      "True\n"
     ]
    }
   ],
   "source": [
    "\"\"\"\n",
    "range(stop)\n",
    "    默认从0开始，直到stop-1\n",
    "    \n",
    "range(start[,stop,step])\n",
    "    start:表示开始\n",
    "    \n",
    "    stop:表示结束(不包括该元素)\n",
    "        \n",
    "    step:表示迭代的步长\n",
    "        默认为1\n",
    "        负值，表示递减\n",
    "\n",
    "\"\"\"\n",
    "\n",
    "# 打印[1-10]之间的数据\n",
    "from collections import Iterable\n",
    "\n",
    "for i in range(1, 11):\n",
    "    print(i, end=\" \")\n",
    "print()\n",
    "\n",
    "for i in range(1, 11, 2):\n",
    "    print(i, end=\" \")\n",
    "print()\n",
    "\n",
    "# 倒序输出\n",
    "for i in range(10, -1, -1):\n",
    "    print(i, end=\" \")\n",
    "print()\n",
    "    \n",
    "for i in range(10, -1, -2):\n",
    "    print(i, end=\" \")\n",
    "print()\n",
    "\n",
    "# 是可迭代的\n",
    "print(isinstance(range(10), Iterable))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "11322ca3",
   "metadata": {},
   "source": [
    "### map函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "e34b9cc3",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-13T14:53:43.701975Z",
     "start_time": "2023-10-13T14:53:43.695783Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "2 4 6 \n",
      "-------------------\n",
      "5 7 9 \n"
     ]
    }
   ],
   "source": [
    "\"\"\"\n",
    "map() 会根据提供的函数对指定序列做映射。\n",
    "第一个参数 function 以参数序列中的每一个元素调用 function 函数，\n",
    "返回包含每次 function 函数返回值的新列表。\n",
    "\n",
    "语法：map(function, iterable, ...)\n",
    "\n",
    "参数说明：\n",
    "    function -- 函数\n",
    "    iterable -- 一个或多个序列\n",
    "\"\"\"\n",
    "from collections import Iterable, Iterator\n",
    "\n",
    "# 创建两个列表\n",
    "list1 = [1, 2, 3]\n",
    "list2 = [4, 5, 6, 7]\n",
    "\n",
    "# 生成一个迭代器：list1中的每一个元素，进行function映射后，返回一个迭代器\n",
    "it1 = map(lambda x: 2*x, list1)\n",
    "\n",
    "# \n",
    "print(isinstance(it1, Iterator))\n",
    "\n",
    "for i in it1:\n",
    "    print(i, end=' ')\n",
    "print()\n",
    "\n",
    "print('-------------------')\n",
    "\n",
    "# list1, list2 中的对应元素，传入 function, 返回一个迭代器\n",
    "it2 = map(lambda x, y: x+y, list1, list2)\n",
    "\n",
    "for i in it2:\n",
    "    print(i, end=' ')\n",
    "print()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "10edf5bb",
   "metadata": {},
   "source": [
    "### filter函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "7f128c40",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-13T14:55:10.920858Z",
     "start_time": "2023-10-13T14:55:10.916685Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "10 25 "
     ]
    }
   ],
   "source": [
    "\"\"\"\n",
    "filter() 函数用于过滤序列，过滤掉不符合条件的元素，返回由符合条件元素组成的新列表。\n",
    "\n",
    "语法：\n",
    "    filter(function, iterable)\n",
    "    \n",
    "参数说明：\n",
    "    function -- 判断函数。\n",
    "    iterable -- 可迭代对象。\n",
    "    \n",
    "返回：\n",
    "    返回迭代器。\n",
    "\"\"\"\n",
    "# 创建一个列表\n",
    "list1 = [1, 2, 3, 0, 10, 0, 25]\n",
    "\n",
    "# 保留list1中 大于等于5的元素\n",
    "it1 = filter(lambda x: x >= 5, list1)\n",
    "for i in it1:\n",
    "    print(i, end=' ')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "32a622b9",
   "metadata": {},
   "source": [
    "### reduce函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "f44ba7d7",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-13T14:57:43.461711Z",
     "start_time": "2023-10-13T14:57:43.457485Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "和为:128\n"
     ]
    }
   ],
   "source": [
    "\"\"\"\n",
    "reduce() \n",
    "\n",
    "函数将一个数据集合（链表，元组等）中的所有数据进行下列操作：\n",
    "    函数 function（有两个参数）先对集合中的第 1、2 个元素进行操作，\n",
    "    得到的结果再与第三个数据用 function 函数运算，最后得到一个结果。\n",
    "    \n",
    "语法：\n",
    "    reduce(function, iterable[, initializer])\n",
    "    \n",
    "参数说明：\n",
    "    function -- 函数，有两个参数\n",
    "    iterable -- 可迭代对象\n",
    "    initializer -- 可选，初始参数\n",
    "    \n",
    "返回：\n",
    "    返回函数计算结果\n",
    "\n",
    "\"\"\"\n",
    "import random\n",
    "from functools import reduce\n",
    "\n",
    "# 生成列表\n",
    "list1 = [37, 6, 33, 40, 12]\n",
    "\n",
    "# 进行累加\n",
    "result = reduce(lambda x, y: x+y, list1)\n",
    "\n",
    "print('和为:%g' % result)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "69630627",
   "metadata": {},
   "source": [
    "### sorted函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "c9d08ae7",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-13T15:02:15.289028Z",
     "start_time": "2023-10-13T15:02:15.279021Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "aaa 19\n",
      "bbb 18\n",
      "ccc 20\n"
     ]
    }
   ],
   "source": [
    "\"\"\"\n",
    "sorted() 函数对所有可迭代的对象进行排序操作。\n",
    "\n",
    "sort 与 sorted 区别：\n",
    "    sort 是应用在 list 上的方法，sorted 可以对所有可迭代的对象进行排序操作。\n",
    "    list 的 sort 方法返回的是对已经存在的列表进行操作，\n",
    "    而内建函数 sorted 方法返回的是一个新的 list，而不会修改原有列表\n",
    "    \n",
    "语法：\n",
    "    sorted(iterable[, key[, reverse]])\n",
    "    \n",
    "参数说明：\n",
    "    iterable -- 可迭代对象。\n",
    "    key -- 主要是用来进行比较的元素，只有一个参数，具体的函数的参数就是取自于可迭代对象中，指定可迭代对象中的一个元素来进行排序。\n",
    "    reverse -- 排序规则，reverse = True 降序， reverse = False 升序（默认）\n",
    "    \n",
    "返回：\n",
    "    返回重新排序的列表。\n",
    "\n",
    "\"\"\"\n",
    "\n",
    "# 列表中自定义对象的排序\n",
    "class Student():\n",
    "    def __init__(self, name, age):\n",
    "        self.name = name\n",
    "        self.age = age\n",
    "\n",
    "stu1 = Student('aaa', 19)\n",
    "stu2 = Student('ccc', 20)\n",
    "stu3 = Student('bbb', 18)\n",
    "\n",
    "list1 = [stu1, stu2, stu3]\n",
    "\n",
    "# 按名字的字母顺序排序\n",
    "list2 = sorted(list1, key=lambda x: x.name)\n",
    "\n",
    "for stu in list2:\n",
    "    print(stu.name, stu.age)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "eeb58cce",
   "metadata": {},
   "source": [
    "## 偏函数\n",
    "把一个函数的某些参数给固定住（也就是设置默认值），返回一个新的函数，调用这个新函数会更简单"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "fd067dde",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-13T15:04:34.681807Z",
     "start_time": "2023-10-13T15:04:34.677030Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "10\n",
      "10\n",
      "10\n"
     ]
    }
   ],
   "source": [
    "\"\"\"\n",
    "偏函数的使用：\n",
    "partial\n",
    "\"\"\"\n",
    "# 导包\n",
    "from functools import partial\n",
    "str1 = '1010'\n",
    "\n",
    "# str1是二进制，将其变为十进制数\n",
    "result = int(str1, 2)\n",
    "print(result)\n",
    "\n",
    "# 定义普通函数\n",
    "def int2(n, base=2):\n",
    "    return int(n, base)\n",
    "\n",
    "result = int2(str1)\n",
    "print(result)\n",
    "\n",
    "# 使用偏函数完成类似的功能\n",
    "int3 = partial(int, base=2)\n",
    "print(int3(str1))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b10525e0",
   "metadata": {},
   "source": [
    "## wraps函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "5bc305e8",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-10-13T15:06:49.329444Z",
     "start_time": "2023-10-13T15:06:49.324640Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "test\n",
      "求x*x的值\n"
     ]
    }
   ],
   "source": [
    "\"\"\"\n",
    "wraps函数的作用：\n",
    "    functools.wraps 可以将原函数对象的指定属性\n",
    "    复制给包装函数对象, 默认有 module、name、doc,或者通过参数选择\n",
    "\"\"\"\n",
    "from functools import wraps\n",
    "\n",
    "\n",
    "def log(func):\n",
    "    @wraps(func)\n",
    "    def with_logging(*args, **kwargs):\n",
    "        print(\"%s was calling\" % func.__name__)\n",
    "        return func(*args, **kwargs)\n",
    "    return with_logging\n",
    "\n",
    "\n",
    "@log # test = log(test)\n",
    "def test(x):\n",
    "    \"\"\"求x*x的值\"\"\"\n",
    "    return x * x\n",
    "\n",
    "\n",
    "print(test.__name__)\n",
    "print(test.__doc__)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f68a69bf",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.12"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {
    "height": "calc(100% - 180px)",
    "left": "10px",
    "top": "150px",
    "width": "265.390625px"
   },
   "toc_section_display": true,
   "toc_window_display": true
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
